package utils

import (
    "crypto/md5"
    "encoding/json"
    "fmt"
    "github.com/w3liu/go-common/constant/timeformat"
    "math/rand"
    "os"
    "sync/atomic"
    "time"
    "unsafe"
)

type KVPair struct {
    Key, Value string
}

func GetNowFormatTodayTime() string {

    now := time.Now()
    dateStr := fmt.Sprintf("%02d-%02d-%02d", now.Year(), int(now.Month()),
        now.Day())

    return dateStr
}

func Md5(str string) string {
    data := []byte(str)
    has := md5.Sum(data)
    return fmt.Sprintf("%x", has) //将[]byte转成16进制
}

func JsonMarshal(v interface{}) string {
    bytes, _ := json.Marshal(v)

    return Bytes2str(bytes)
}

func Str2bytes(s string) []byte {
    x := (*[2]uintptr)(unsafe.Pointer(&s))
    h := [3]uintptr{x[0], x[1], x[1]}
    return *(*[]byte)(unsafe.Pointer(&h))
}

func Bytes2str(b []byte) string {
    return *(*string)(unsafe.Pointer(&b))
}

// RecoverPanic 恢复panic
func RecoverPanic() {
    err := recover()
    if err != nil {
        fmt.Println("RecoverPanic异常：", err)
    }
}

func JsonMarshalByte(v interface{}) []byte {
    bytes, err := json.Marshal(v)
    if err != nil {
        return nil
    }
    return bytes
}

func JsonUnmarshal(str string, v interface{}) {
    err := json.Unmarshal(Str2bytes(str), v)
    if err != nil {
        //logger.Sugar.Error("json反序列化：", err)
    }
    return
}

//生成24位订单号
//前面17位代表时间精确到毫秒，中间3位代表进程id，最后4位代表序号
func Generate(t time.Time) string {
    var num int64
    s := t.Format(timeformat.Continuity)
    m := t.UnixNano()/1e6 - t.UnixNano()/1e9*1e3
    ms := sup(m, 3)
    p := os.Getpid() % 1000
    ps := sup(int64(p), 3)
    i := atomic.AddInt64(&num, 1)
    r := i % 10000
    rs := sup(r, 4)
    n := fmt.Sprintf("%s%s%s%s", s, ms, ps, rs)
    return n
}

//对长度不足n的数字前面补0
func sup(i int64, n int) string {
    m := fmt.Sprintf("%d", i)
    for len(m) < n {
        m = fmt.Sprintf("0%s", m)
    }
    return m
}

//GetUUID 获取随机字符串
func GetUUID() (string, error) {
    r := rand.New(rand.NewSource(time.Now().UnixNano()))
    b := make([]rune, 32)
    letters := []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
    for i := range b {
        b[i] = letters[r.Intn(len(letters))]
    }
    return string(b), nil
}

//var mutex sync.Mutex
//func Lock(key string) bool {
//    mutex.Lock()
//    defer mutex.Unlock()
//    bool, err := global.Redis.SetNX(key, 1, 10*time.Second).Result()
//    if err != nil {
//        log.Println(err.Error())
//    }
//    return bool
//}
//func UnLock(key string) int64 {
//    nums, err := global.Redis.Del(key).Result()
//    if err != nil {
//        log.Println(err.Error())
//        return 0
//    }
//    return nums
//}